package com.asiainfo.ncrm.util;

import java.security.*;

import java.util.Random;
import javax.crypto.*;

public class DESEngine {
	private Cipher encryptCipher = null;
	private Cipher decryptCipher = null;

	public static String byteArr2HexStr(byte[] arrB) throws Exception {
		int iLen = arrB.length;

		StringBuffer sb = new StringBuffer(iLen * 2);
		for (int i = 0; i < iLen; i++) {
			int intTmp = arrB[i];

			while (intTmp < 0) {
				intTmp = intTmp + 256;
			}

			if (intTmp < 16) {
				sb.append("0");
			}
			sb.append(Integer.toString(intTmp, 16));
		}
		return sb.toString();
	}

	public static byte[] hexStr2ByteArr(String strIn) throws Exception {
		byte[] arrB = strIn.getBytes();
		int iLen = arrB.length;
		
		byte[] arrOut = new byte[iLen / 2];
		for (int i = 0; i < iLen; i = i + 2) {
			String strTmp = new String(arrB, i, 2);
			arrOut[i / 2] = (byte) Integer.parseInt(strTmp, 16);
		}
		return arrOut;
	}

	private static DESEngine single = new DESEngine();

	public DESEngine() {
	}

	public static DESEngine getInstance() {
		return single;
	}

	private void init(String strKey) throws Exception {
		Security.addProvider(new com.sun.crypto.provider.SunJCE());
		Key key = getKey(strKey.getBytes());

		encryptCipher = Cipher.getInstance("DES/ECB/NoPadding", "SunJCE");
		encryptCipher.init(Cipher.ENCRYPT_MODE, key);

		decryptCipher = Cipher.getInstance("DES/ECB/NoPadding", "SunJCE");
		decryptCipher.init(Cipher.DECRYPT_MODE, key);
	}
	
	private void initb(byte[] key_b) throws Exception {
		Security.addProvider(new com.sun.crypto.provider.SunJCE());
		Key key = getKey(key_b);

		encryptCipher = Cipher.getInstance("DES/ECB/NoPadding", "SunJCE");
		encryptCipher.init(Cipher.ENCRYPT_MODE, key);

		decryptCipher = Cipher.getInstance("DES/ECB/NoPadding", "SunJCE");
		decryptCipher.init(Cipher.DECRYPT_MODE, key);
	}

	public byte[] encrypt(byte[] arrB) throws Exception {
		return encryptCipher.doFinal(arrB);
	}

	public byte[] decrypt(byte[] arrB) throws Exception {
		return decryptCipher.doFinal(arrB);
	}

	private Key getKey(byte[] arrBTmp) throws Exception {
		byte[] arrB = new byte[8];
		for (int i = 0; i < arrBTmp.length && i < arrB.length; i++) {
			arrB[i] = arrBTmp[i];
		}
		Key key = new javax.crypto.spec.SecretKeySpec(arrB, "DES");

		return key;
	}

	public String encrypt(String key, String strIn) throws Exception {
		this.init(key);
		byte[] inb = strIn.getBytes();
		int length = inb.length;
		int mod = length % 8;
		if (mod != 0) {
			mod = 8 - mod;
		}
		byte[] newin = new byte[length + mod];
		for (int u = 0; u < length; u++) {
			newin[u] = inb[u];
		}
		// 给存储明文的字节数组a的不足位补0
		for (int u = length; u < newin.length; u++) {
			newin[u] = 0;
		}

		return byteArr2HexStr(encrypt(newin));
	}
	
	public byte [] encryptB(byte[] key, byte [] inb) throws Exception {
		this.initb(key);
		
		int length = inb.length;
		int mod = length % 8;
		if (mod != 0) {
			mod = 8 - mod;
		}
		byte[] newin = new byte[length + mod];
		for (int u = 0; u < length; u++) {
			newin[u] = inb[u];
		}
		// 给存储明文的字节数组a的不足位补0
		for (int u = length; u < newin.length; u++) {
			newin[u] = 0;
		}
		
		return encrypt(newin);
	}

	/*
	 * 解密方法
	 */
	public String decrypt(String key, String strIn) throws Exception {
		this.init(key);
		return new String(decrypt(hexStr2ByteArr(strIn)));
	}
	
	public byte [] decryptB(byte [] key, byte [] inb) throws Exception {
		this.initb(key);
		return decrypt(inb);
	}

	public static void main(String[] args) {
//		String s = "87654321";
//		byte[] b = s.getBytes();
//		byte[] c = new byte[2 * s.length() - 1];
//		for (int i = 0; i < c.length; i++) {
//			if (i % 2 == 0) {
//				c[i] = b[i / 2];
//			} else {
//				Random r = new Random();
//				byte[] d = new byte[1];
//				r.nextBytes(d);
//				c[i] = d[0];
//			}
//		}
//		System.out.println(new String(c));
//		byte[] f = new byte[(c.length + 1) / 2];
//		for (int i = 0; i < f.length; i++) {
//			f[i] = c[i * 2];
//		}
//		System.out.println(new String(f));
//		System.out.println(new String(f).equals(s));
		try {
			String test = "33333333";
			DESEngine des = new DESEngine();			
			DESEngine des2 = new DESEngine();
			System.out.println(des.encrypt("Wzhbgapp2015", test));
			System.out.println("plain:"
					+ des2.decrypt("Wzhbgapp2015", des.encrypt("Wzhbgapp2015", test))
							);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
